home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / MPW / gawk 2.11.1r3 / Sources / awk.h < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-02  |  16.7 KB  |  638 lines  |  [TEXT/MPS ]

  1. /*
  2.  * awk.h -- Definitions for gawk. 
  3.  */
  4.  
  5. /* 
  6.  * Copyright (C) 1986, 1988, 1989 the Free Software Foundation, Inc.
  7.  * 
  8.  * This file is part of GAWK, the GNU implementation of the
  9.  * AWK Progamming Language.
  10.  * 
  11.  * GAWK is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 1, or (at your option)
  14.  * any later version.
  15.  * 
  16.  * GAWK is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  * 
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with GAWK; see the file COPYING.  If not, write to
  23.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25.  
  26. /* 02Jun91    Matthias Neeracher    <neeri@iis.ethz.ch>    MPW port */
  27.  
  28. /* ------------------------------ Includes ------------------------------ */
  29. #include <stdio.h>
  30. #include <ctype.h>
  31. #include <setjmp.h>
  32.  
  33. #ifndef macintosh
  34. #include <varargs.h>
  35. #include <sys/types.h>
  36. #include <sys/stat.h>
  37. #define    SpinMacCursor(N)
  38. #else
  39. #include <stdarg.h>
  40. #include <string.h>
  41. #include <CursorCtl.h>
  42. #include "stat.h"
  43. #define    SpinMacCursor(N)    SpinCursor(N)
  44.  
  45. extern int mpw_regex;
  46. #endif
  47.  
  48. #include <errno.h>
  49.  
  50. #include "regex.h"
  51.  
  52. /* ------------------- System Functions, Variables, etc ------------------- */
  53. /* nasty nasty SunOS-ism */
  54. #ifdef sparc
  55. #include <alloca.h>
  56. #ifdef lint
  57. extern char *alloca();
  58. #endif
  59. #else
  60. extern char *alloca();
  61. #endif
  62. #ifndef macintosh
  63. #ifdef SPRINTF_INT
  64. extern int sprintf();
  65. #else    /* not USG */
  66. /* nasty nasty berkelixm */
  67. #define setjmp    _setjmp
  68. #define longjmp    _longjmp
  69.  
  70. extern char *sprintf();
  71. #endif
  72. #endif
  73.  
  74. /*
  75.  * if you don't have vprintf, but you are BSD, the version defined in
  76.  * vprintf.c should do the trick.  Otherwise, use this and cross your fingers.
  77.  */
  78. #if defined(VPRINTF_MISSING) && !defined(DOPRNT_MISSING) && !defined(BSDSTDIO)
  79. #define vfprintf(fp,fmt,arg)    _doprnt((fmt), (arg), (fp))
  80. #endif
  81.  
  82. /* What the *ç%ç& is the purpose of these prototypes ? */
  83.  
  84. #ifndef macintosh
  85. #ifdef __STDC__
  86. extern void *malloc(unsigned), *realloc(void *, unsigned);
  87. extern void free(char *);
  88. extern char *getenv(char *);
  89.  
  90. extern char *strcpy(char *, char *), *strcat(char *, char *), *strncpy(char *, char *, int);
  91. extern int strcmp(char *, char *);
  92. extern int strncmp(char *, char *, int);
  93. extern int strncasecmp(char *, char *, int);
  94. extern char *strerror(int);
  95. extern char *strchr(char *, int);
  96. extern int strlen(char *);
  97. extern    char *memcpy(char *, char *, int);
  98. extern    int memcmp(char *, char *, int);
  99. extern    char *memset(char *, int, int);
  100.  
  101. /* extern int fprintf(FILE *, char *, ...); */
  102. extern int fprintf();
  103. extern int vfprintf();
  104. #ifndef MSDOS
  105. extern int fwrite(char *, int, int, FILE *);
  106. #endif
  107. extern int fflush(FILE *);
  108. extern int fclose(FILE *);
  109. extern int pclose(FILE *);
  110. #ifndef MSDOS
  111. extern int fputs(char *, FILE *);
  112. #endif
  113. extern void abort();
  114. extern int isatty(int);
  115. extern void exit(int);
  116. extern int system(char *);
  117. extern int sscanf(/* char *, char *, ... */);
  118.  
  119. extern double atof(char *);
  120. extern int fstat(int, struct stat *);
  121. extern off_t lseek(int, off_t, int);
  122. extern int fseek(FILE *, long, int);
  123. extern int close(int);
  124. extern int open();
  125. extern int pipe(int *);
  126. extern int dup2(int, int);
  127. #ifndef MSDOS
  128. extern int unlink(char *);
  129. #endif
  130. extern int fork();
  131. extern int execl(/* char *, char *, ... */);
  132. extern int read(int, char *, int);
  133. extern int wait(int *);
  134. extern void _exit(int);
  135. #else
  136. extern void _exit();
  137. extern int wait();
  138. extern int read();
  139. extern int execl();
  140. extern int fork();
  141. extern int unlink();
  142. extern int dup2();
  143. extern int pipe();
  144. extern int open();
  145. extern int close();
  146. extern int fseek();
  147. extern off_t lseek();
  148. extern int fstat();
  149. extern void exit();
  150. extern int system();
  151. extern int isatty();
  152. extern void abort();
  153. extern int fputs();
  154. extern int fclose();
  155. extern int pclose();
  156. extern int fflush();
  157. extern int fwrite();
  158. extern int fprintf();
  159. extern int vfprintf();
  160. extern int sscanf();
  161. extern char *malloc(), *realloc();
  162. extern void free();
  163. extern char *getenv();
  164.  
  165. extern int strcmp();
  166. extern int strncmp();
  167. extern int strncasecmp();
  168. extern int strlen();
  169. extern char *strcpy(), *strcat(), *strncpy();
  170. extern    char *memset();
  171. extern    int memcmp();
  172. extern    char *memcpy();
  173. extern char *strerror();
  174. extern char *strchr();
  175.  
  176. extern double atof();
  177. #endif
  178.  
  179. #ifndef MSDOS
  180. extern int errno;
  181. #endif    /* MSDOS */
  182. #endif 
  183.  
  184. /* ------------------ Constants, Structures, Typedefs  ------------------ */
  185. #define AWKNUM    double
  186.  
  187. typedef enum {
  188.     /* illegal entry == 0 */
  189.     Node_illegal,
  190.  
  191.     /* binary operators  lnode and rnode are the expressions to work on */
  192.     Node_times,
  193.     Node_quotient,
  194.     Node_mod,
  195.     Node_plus,
  196.     Node_minus,
  197.     Node_cond_pair,        /* conditional pair (see Node_line_range) */
  198.     Node_subscript,
  199.     Node_concat,
  200.     Node_exp,
  201.  
  202.     /* unary operators   subnode is the expression to work on */
  203. /*10*/    Node_preincrement,
  204.     Node_predecrement,
  205.     Node_postincrement,
  206.     Node_postdecrement,
  207.     Node_unary_minus,
  208.     Node_field_spec,
  209.  
  210.     /* assignments   lnode is the var to assign to, rnode is the exp */
  211.     Node_assign,
  212.     Node_assign_times,
  213.     Node_assign_quotient,
  214.     Node_assign_mod,
  215. /*20*/    Node_assign_plus,
  216.     Node_assign_minus,
  217.     Node_assign_exp,
  218.  
  219.     /* boolean binaries   lnode and rnode are expressions */
  220.     Node_and,
  221.     Node_or,
  222.  
  223.     /* binary relationals   compares lnode and rnode */
  224.     Node_equal,
  225.     Node_notequal,
  226.     Node_less,
  227.     Node_greater,
  228.     Node_leq,
  229. /*30*/    Node_geq,
  230.     Node_match,
  231.     Node_nomatch,
  232.  
  233.     /* unary relationals   works on subnode */
  234.     Node_not,
  235.  
  236.     /* program structures */
  237.     Node_rule_list,        /* lnode is a rule, rnode is rest of list */
  238.     Node_rule_node,        /* lnode is pattern, rnode is statement */
  239.     Node_statement_list,    /* lnode is statement, rnode is more list */
  240.     Node_if_branches,    /* lnode is to run on true, rnode on false */
  241.     Node_expression_list,    /* lnode is an exp, rnode is more list */
  242.     Node_param_list,    /* lnode is a variable, rnode is more list */
  243.  
  244.     /* keywords */
  245. /*40*/    Node_K_if,        /* lnode is conditonal, rnode is if_branches */
  246.     Node_K_while,        /* lnode is condtional, rnode is stuff to run */
  247.     Node_K_for,        /* lnode is for_struct, rnode is stuff to run */
  248.     Node_K_arrayfor,    /* lnode is for_struct, rnode is stuff to run */
  249.     Node_K_break,        /* no subs */
  250.     Node_K_continue,    /* no stuff */
  251.     Node_K_print,        /* lnode is exp_list, rnode is redirect */
  252.     Node_K_printf,        /* lnode is exp_list, rnode is redirect */
  253.     Node_K_next,        /* no subs */
  254.     Node_K_exit,        /* subnode is return value, or NULL */
  255.     Node_K_do,        /* lnode is conditional, rnode stuff to run */
  256.     Node_K_return,
  257.     Node_K_delete,
  258.     Node_K_getline,
  259.     Node_K_function,    /* lnode is statement list, rnode is params */
  260.  
  261.     /* I/O redirection for print statements */
  262.     Node_redirect_output,    /* subnode is where to redirect */
  263.     Node_redirect_append,    /* subnode is where to redirect */
  264.     Node_redirect_pipe,    /* subnode is where to redirect */
  265.     Node_redirect_pipein,    /* subnode is where to redirect */
  266.     Node_redirect_input,    /* subnode is where to redirect */
  267.  
  268.     /* Variables */
  269.     Node_var,        /* rnode is value, lnode is array stuff */
  270.     Node_var_array,        /* array is ptr to elements, asize num of
  271.                  * eles */
  272.     Node_val,        /* node is a value - type in flags */
  273.  
  274.     /* Builtins   subnode is explist to work on, proc is func to call */
  275.     Node_builtin,
  276.  
  277.     /*
  278.      * pattern: conditional ',' conditional ;  lnode of Node_line_range
  279.      * is the two conditionals (Node_cond_pair), other word (rnode place)
  280.      * is a flag indicating whether or not this range has been entered.
  281.      */
  282.     Node_line_range,
  283.  
  284.     /*
  285.      * boolean test of membership in array lnode is string-valued
  286.      * expression rnode is array name 
  287.      */
  288.     Node_in_array,
  289.  
  290.     Node_func,        /* lnode is param. list, rnode is body */
  291.     Node_func_call,        /* lnode is name, rnode is argument list */
  292.  
  293.     Node_cond_exp,        /* lnode is conditonal, rnode is if_branches */
  294.     Node_regex,
  295.     Node_hashnode,
  296.     Node_ahash,
  297. } NODETYPE;
  298.  
  299. /*
  300.  * NOTE - this struct is a rather kludgey -- it is packed to minimize
  301.  * space usage, at the expense of cleanliness.  Alter at own risk.
  302.  */
  303. typedef struct exp_node {
  304.     union {
  305.         struct {
  306.             union {
  307.                 struct exp_node *lptr;
  308.                 char *param_name;
  309.                 char *retext;
  310.                 struct exp_node *nextnode;
  311.             } l;
  312.             union {
  313.                 struct exp_node *rptr;
  314.                 struct exp_node *(*pptr) ();
  315.                 struct re_pattern_buffer *preg;
  316.                 struct for_loop_header *hd;
  317.                 struct exp_node **av;
  318.                 int r_ent;    /* range entered */
  319.             } r;
  320.             char *name;
  321.             short number;
  322.             unsigned char recase;
  323.         } nodep;
  324.         struct {
  325.             AWKNUM fltnum;    /* this is here for optimal packing of
  326.                      * the structure on many machines
  327.                      */
  328.             char *sp;
  329.             short slen;
  330.             unsigned char sref;
  331.         } val;
  332.         struct {
  333.             struct exp_node *next;
  334.             char *name;
  335.             int length;
  336.             struct exp_node *value;
  337.         } hash;
  338. #define    hnext    sub.hash.next
  339. #define    hname    sub.hash.name
  340. #define    hlength    sub.hash.length
  341. #define    hvalue    sub.hash.value
  342.         struct {
  343.             struct exp_node *next;
  344.             struct exp_node *name;
  345.             struct exp_node *value;
  346.         } ahash;
  347. #define    ahnext    sub.ahash.next
  348. #define    ahname    sub.ahash.name
  349. #define    ahvalue    sub.ahash.value
  350.     } sub;
  351.     NODETYPE type;
  352.     unsigned char flags;
  353. #            define    MEM    0x7
  354. #            define    MALLOC    1    /* can be free'd */
  355. #            define    TEMP    2    /* should be free'd */
  356. #            define    PERM    4    /* can't be free'd */
  357. #            define    VAL    0x18
  358. #            define    NUM    8    /* numeric value is valid */
  359. #            define    STR    16    /* string value is valid */
  360. #            define    NUMERIC    32    /* entire field is numeric */
  361. } NODE;
  362.  
  363. #define lnode    sub.nodep.l.lptr
  364. #define nextp    sub.nodep.l.nextnode
  365. #define rnode    sub.nodep.r.rptr
  366. #define source_file    sub.nodep.name
  367. #define    source_line    sub.nodep.number
  368. #define    param_cnt    sub.nodep.number
  369. #define param    sub.nodep.l.param_name
  370.  
  371. #define subnode    lnode
  372. #define proc    sub.nodep.r.pptr
  373.  
  374. #define reexp    lnode
  375. #define rereg    sub.nodep.r.preg
  376. #define re_case sub.nodep.recase
  377. #define re_text sub.nodep.l.retext
  378.  
  379. #define forsub    lnode
  380. #define forloop    rnode->sub.nodep.r.hd
  381.  
  382. #define stptr    sub.val.sp
  383. #define stlen    sub.val.slen
  384. #define stref    sub.val.sref
  385. #define    valstat    flags
  386.  
  387. #define numbr    sub.val.fltnum
  388.  
  389. #define var_value lnode
  390. #define var_array sub.nodep.r.av
  391.  
  392. #define condpair lnode
  393. #define triggered sub.nodep.r.r_ent
  394.  
  395. #define HASHSIZE 101
  396.  
  397. typedef struct for_loop_header {
  398.     NODE *init;
  399.     NODE *cond;
  400.     NODE *incr;
  401. } FOR_LOOP_HEADER;
  402.  
  403. /* for "for(iggy in foo) {" */
  404. struct search {
  405.     int numleft;
  406.     NODE **arr_ptr;
  407.     NODE *bucket;
  408.     NODE *retval;
  409. };
  410.  
  411. /* for faster input, bypass stdio */
  412. typedef struct iobuf {
  413.     int fd;
  414.     char *buf;
  415.     char *off;
  416.     int size;    /* this will be determined by an fstat() call */
  417.     int cnt;
  418.     char *secbuf;
  419.     int secsiz;
  420.     int flag;
  421. #    define        IOP_IS_TTY    1
  422. } IOBUF;
  423.  
  424. /*
  425.  * structure used to dynamically maintain a linked-list of open files/pipes
  426.  */
  427. struct redirect {
  428.     int flag;
  429. #        define        RED_FILE    1
  430. #        define        RED_PIPE    2
  431. #        define        RED_READ    4
  432. #        define        RED_WRITE    8
  433. #        define        RED_APPEND    16
  434. #        define        RED_NOBUF    32
  435.     char *value;
  436.     FILE *fp;
  437.     IOBUF *iop;
  438.     int pid;
  439.     int status;
  440.     long offset;        /* used for dynamic management of open files */
  441.     struct redirect *prev;
  442.     struct redirect *next;
  443. };
  444.  
  445. /* longjmp return codes, must be nonzero */
  446. /* Continue means either for loop/while continue, or next input record */
  447. #define TAG_CONTINUE 1
  448. /* Break means either for/while break, or stop reading input */
  449. #define TAG_BREAK 2
  450. /* Return means return from a function call; leave value in ret_node */
  451. #define    TAG_RETURN 3
  452.  
  453. #ifdef MSDOS
  454. #define HUGE    0x7fff
  455. #else
  456. #define HUGE    0x7fffffff
  457. #endif
  458.  
  459. /* -------------------------- External variables -------------------------- */
  460. /* gawk builtin variables */
  461. extern NODE *FS_node, *NF_node, *RS_node, *NR_node;
  462. extern NODE *FILENAME_node, *OFS_node, *ORS_node, *OFMT_node;
  463. extern NODE *FNR_node, *RLENGTH_node, *RSTART_node, *SUBSEP_node;
  464. extern NODE *IGNORECASE_node;
  465.  
  466. extern NODE **stack_ptr;
  467. extern NODE *Nnull_string;
  468. extern NODE *deref;
  469. extern NODE **fields_arr;
  470. extern int sourceline;
  471. extern char *source;
  472. extern NODE *expression_value;
  473.  
  474. extern NODE *variables[];
  475.  
  476. extern NODE *_t;    /* used as temporary in tree_eval */
  477.  
  478. extern char *myname;
  479.  
  480. extern int node0_valid;
  481. extern int field_num;
  482. extern int strict;
  483.  
  484. /* ------------------------- Pseudo-functions ------------------------- */
  485. #define is_identchar(c) (isalnum(c) || (c) == '_')
  486.  
  487.  
  488. #define    free_temp(n)    if ((n)->flags&TEMP) { deref = (n); do_deref(); } else
  489. #define    tree_eval(t)    (_t = (t),(_t) == NULL ? Nnull_string : \
  490.             ((_t)->type == Node_val ? (_t) : r_tree_eval((_t))))
  491. #define    make_string(s,l)    make_str_node((s),(l),0)
  492.  
  493. #ifndef macintosh
  494. #define    cant_happen()    fatal("line %d, file: %s; bailing out", \
  495.                 __LINE__, __FILE__);
  496. #else
  497. #define    cant_happen()    fatal("File %s; Line %d # bailing out", \
  498.                 __FILE__, __LINE__);
  499. #endif
  500. #ifdef MEMDEBUG
  501. #define memmsg(x,y,z,zz)    fprintf(stderr, "malloc: %s: %s: %d %0x\n", z, x, y, zz)
  502. #define free(s)    fprintf(stderr, "free: s: %0x\n", s), do_free(s)
  503. #else
  504. #define memmsg(x,y,z,zz)
  505. #endif
  506.  
  507. #define    emalloc(var,ty,x,str)    if ((var = (ty) malloc((unsigned)(x))) == NULL)\
  508.                     fatal("%s: %s: can't allocate memory (%s)",\
  509.                     (str), "var", strerror(errno)); else\
  510.                     memmsg("var", x, str, var)
  511. #define    erealloc(var,ty,x,str)    if((var=(ty)realloc((char *)var,\
  512.                         (unsigned)(x)))==NULL)\
  513.                     fatal("%s: %s: can't allocate memory (%s)",\
  514.                     (str), "var", strerror(errno)); else\
  515.                     memmsg("re: var", x, str, var)
  516. #ifdef DEBUG
  517. #define    force_number    r_force_number
  518. #define    force_string    r_force_string
  519. #else
  520. #ifdef lint
  521. extern AWKNUM force_number();
  522. #endif
  523. #ifdef MSDOS
  524. extern double _msc51bug;
  525. #define    force_number(n)    (_msc51bug=(_t = (n),(_t->flags & NUM) ? _t->numbr : r_force_number(_t)))
  526. #else
  527. #define    force_number(n)    (_t = (n),(_t->flags & NUM) ? _t->numbr : r_force_number(_t))
  528. #endif
  529. #define    force_string(s)    (_t = (s),(_t->flags & STR) ? _t : r_force_string(_t))
  530. #endif
  531.  
  532. #define    STREQ(a,b)    (*(a) == *(b) && strcmp((a), (b)) == 0)
  533. #define    STREQN(a,b,n)    ((n) && *(a) == *(b) && strncmp((a), (b), (n)) == 0)
  534.  
  535. #define    WHOLELINE    (node0_valid ? fields_arr[0] : *get_field(0,0))
  536.  
  537. /* ------------- Function prototypes or defs (as appropriate) ------------- */
  538. #ifdef __STDC__
  539. extern    int parse_escape(char **);
  540. extern    int devopen(char *, char *);
  541. extern    struct re_pattern_buffer *make_regexp(NODE *, int);
  542. extern    struct re_pattern_buffer *mk_re_parse(char *, int);
  543. extern    NODE *variable(char *);
  544. extern    NODE *install(NODE **, char *, NODE *);
  545. extern    NODE *lookup(NODE **, char *);
  546. extern    NODE *make_name(char *, NODETYPE);
  547. extern    int interpret(NODE *);
  548. extern    NODE *r_tree_eval(NODE *);
  549. extern    void assign_number(NODE **, double);
  550. extern    int cmp_nodes(NODE *, NODE *);
  551. extern    struct redirect *redirect(NODE *, int *);
  552. extern    int flush_io(void);
  553. extern    void print_simple(NODE *, FILE *);
  554. /* extern    void warning(char *,...); */
  555. extern    void warning();
  556. /* extern    void fatal(char *,...); */
  557. extern    void fatal();
  558. extern    void set_record(char *, int);
  559. extern    NODE **get_field(int, int);
  560. extern    NODE **get_lhs(NODE *, int);
  561. extern    void do_deref(void );
  562. extern    struct search *assoc_scan(NODE *);
  563. extern    struct search *assoc_next(struct search *);
  564. extern    NODE **assoc_lookup(NODE *, NODE *);
  565. extern    double r_force_number(NODE *);
  566. extern    NODE *r_force_string(NODE *);
  567. extern    NODE *newnode(NODETYPE);
  568. extern    NODE *dupnode(NODE *);
  569. extern    NODE *make_number(double);
  570. extern    NODE *tmp_number(double);
  571. extern    NODE *make_str_node(char *, int, int);
  572. extern    NODE *tmp_string(char *, int);
  573. extern    char *re_compile_pattern(char *, int, struct re_pattern_buffer *);
  574. extern    int re_search(struct re_pattern_buffer *, char *, int, int, int, struct re_registers *);
  575. extern    void freenode(NODE *);
  576.  
  577. #else
  578. extern    int parse_escape();
  579. extern    void freenode();
  580. extern    int devopen();
  581. extern    struct re_pattern_buffer *make_regexp();
  582. extern    struct re_pattern_buffer *mk_re_parse();
  583. extern    NODE *variable();
  584. extern    NODE *install();
  585. extern    NODE *lookup();
  586. extern    int interpret();
  587. extern    NODE *r_tree_eval();
  588. extern    void assign_number();
  589. extern    int cmp_nodes();
  590. extern    struct redirect *redirect();
  591. extern    int flush_io();
  592. extern    void print_simple();
  593. extern    void warning();
  594. extern    void fatal();
  595. extern    void set_record();
  596. extern    NODE **get_field();
  597. extern    NODE **get_lhs();
  598. extern    void do_deref();
  599. extern    struct search *assoc_scan();
  600. extern    struct search *assoc_next();
  601. extern    NODE **assoc_lookup();
  602. extern    double r_force_number();
  603. extern    NODE *r_force_string();
  604. extern    NODE *newnode();
  605. extern    NODE *dupnode();
  606. extern    NODE *make_number();
  607. extern    NODE *tmp_number();
  608. extern    NODE *make_str_node();
  609. extern    NODE *tmp_string();
  610. extern    char *re_compile_pattern();
  611. extern    int re_search();
  612. #endif
  613.  
  614. #if !defined(__STDC__) || __STDC__ <= 0
  615. #define volatile
  616. #endif
  617.  
  618. /* Figure out what '\a' really is. */
  619. #ifdef __STDC__
  620. #define BELL    '\a'        /* sure makes life easy, don't it? */
  621. #else
  622. #    if 'z' - 'a' == 25    /* ascii */
  623. #        if 'a' != 97    /* machine is dumb enough to use mark parity */
  624. #            define BELL    '\207'
  625. #        else
  626. #            define BELL    '\07'
  627. #        endif
  628. #    else
  629. #        define BELL    '\057'
  630. #    endif
  631. #endif
  632.  
  633. #ifndef SIGTYPE
  634. #define SIGTYPE    void
  635. #endif
  636.  
  637. extern char casetable[];    /* for case-independent regexp matching */
  638.